﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Controls;
using System.Windows.Forms;
using CapstoneProjectAEReader.GUIs.LibraryGUI;
using CapstoneProjectAEReader.Entities.Models;
using CapstoneProjectAEReader.Common.Utility;
using CapstoneProjectAEReader.DataAccess.DBAccess;
using CapstoneProjectAEReader.GUIs.ReaderGUI;
using Button = System.Windows.Controls.Button;
using MessageBox = System.Windows.Forms.MessageBox;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
using Path = System.IO.Path;
using CapstoneProjectAEReader.Business.Others;
using Message = CapstoneProjectAEReader.GUIs.LibraryGUI.Message;
using TabControl = System.Windows.Forms.TabControl;

namespace CapstoneProjectAEReader.GUIs
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    /// 
    public partial class MainWindow : Window
    {
        #region Attributes

        //const strings
        private const string GeneralTabName = "generalTab";
        private const string EbookTabName = "ebookTab";
        private const string NoteTabName = "noteTab";
        private const string SettingName = "settingTab";
        private const string OpenFileName = "openFileButton";
        private const string ImportFilesName = "importFilesButton";
        private const string ExitName = "exitButton";
        private const string OpenEbook = "statusOpenind";
        private const string TabHeader = "TabHeader";

        private LibraryGUI.LocalLibrary _library;
        private DictionaryGUI.NoteManagement _noteManagement;
        private SettingGUI.Setting _setting;
        private SyncManager _syncManager;
        private readonly List<TabItem> _tabItems;
        private DTO _dto;
        private readonly FileHandler _fileHandler = new FileHandler();
        private string _currentTabHeader;
        private Dictionary<string,ReaderGUI.ReaderGui> _openingEbook = new Dictionary<string, ReaderGui>();

        public string[] ArrNoteDetail;

        public NoteDetail NoteDetailData;
        //Binding To New Control
        private GetHeaderText _getHeaderTextClass;

        #endregion

        public GetHeaderText HeaderClass
        {
            get { return _getHeaderTextClass; }
        }

        public class GetHeaderText
        {
            public string GeneralTabString
            {
                get { return ResourceReader.GetResourceContent(GeneralTabName); }
            }

            public string EBookString
            {
                get { return ResourceReader.GetResourceContent(EbookTabName); }
            }

            public string NoteString
            {
                get { return ResourceReader.GetResourceContent(NoteTabName); }
            }

            public string SettingString
            {
                get { return ResourceReader.GetResourceContent(SettingName); }
            }

            public string OpenString
            {
                get { return ResourceReader.GetResourceContent(OpenFileName); }
            }

            public string ImportString
            {
                get { return ResourceReader.GetResourceContent(ImportFilesName); }
            }

            public string ExitString
            {
                get { return ResourceReader.GetResourceContent(ExitName); }
            }
        }

        public LocalLibrary Library
        {
            get { return _library; }
            set { _library = value; }
        }

        public MainWindow()
        {
            InitializeComponent();
            _tabItems = new List<TabItem>();
            Utilities.BuildDirectoryStructure();
            _syncManager = new SyncManager(1);
            //Initiate DTO
            if (Utilities.CheckFileExist(Constants.StorageStructure.ApplicationData))
            {
                _dto = _fileHandler.ReadFile(Constants.StorageStructure.ApplicationData);
            }
            else
            {
                _dto = new DTO {SettingDetail = {ApplicationLanguage = Constants.SettingSupporter.Vietnamese}};
                var unGroup = new EbookGroup {Groupid = 1, Groupname = Constants.UnGroup};
                _dto.EbookGroup.Add(unGroup);
                DAO.CommitData(_dto);
            }

            //Initiate language object
            ResourceReader.Initialize(_dto.SettingDetail.ApplicationLanguage);
            ReloadFormLanguage();

            //Load Form title
            Title = Constants.ApplicationTitle;
            OpenEbookTab();
        }


        public DTO Dto
        {
            get { return _dto; }
            set { _dto = value; }
        }

        /// <summary>
        /// Reload form language base on settings
        /// </summary>
        public void ReloadFormLanguage()
        {
            _getHeaderTextClass = new GetHeaderText();
        }

        private string CreateNewTagName()
        {
            string tabName = Utilities.GenerateRandomString();
            while (_tabItems.Any(x => x.Name == tabName))
            {
                tabName = Utilities.GenerateRandomString();
            }
            return tabName;
        }

        private void ImportHandler(object sender, RoutedEventArgs e)
        {
            bool blnAdd = true;
            Dictionary<int, int> dicEbooks = new Dictionary<int, int>();
            Dictionary<int, int> dicNote = new Dictionary<int, int>();
            FolderBrowserDialog folderBrowserDg = new FolderBrowserDialog();
            string strEbookImportPath;
            if (folderBrowserDg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                _dto = _fileHandler.ReadFile(Constants.StorageStructure.ApplicationData);
                DTO dtoImport =
                    _fileHandler.ReadFile(folderBrowserDg.SelectedPath + Constants.CommonCharacters.SlashString +
                                          Constants.DatFileName);
                DTO dtoImportTemp1 =
                    _fileHandler.ReadFile(folderBrowserDg.SelectedPath + Constants.CommonCharacters.SlashString +
                                          Constants.DatFileName);
                DTO dtoImportTemp2 =
                    _fileHandler.ReadFile(folderBrowserDg.SelectedPath + Constants.CommonCharacters.SlashString +
                                          Constants.DatFileName);
                DTO dtoImportTemp3 =
                    _fileHandler.ReadFile(folderBrowserDg.SelectedPath + Constants.CommonCharacters.SlashString +
                                          Constants.DatFileName);
                strEbookImportPath = folderBrowserDg.SelectedPath + Constants.CommonCharacters.SlashString +
                                     Constants.StorageStructure.Ebook;
                //sync
                if (dtoImport.Ebooks.Count > 0)
                {
                    for (int i = 0; i < dtoImport.Ebooks.Count; i++)
                    {
                        for (int j = 0; j < _dto.Ebooks.Count; j++)
                        {
                            blnAdd = true;
                            if (dtoImport.Ebooks.ElementAt(i).Author.Equals(_dto.Ebooks.ElementAt(j).Author) &&
                                dtoImport.Ebooks.ElementAt(i).Title.Equals(_dto.Ebooks.ElementAt(j).Title))
                            {
                                blnAdd = false;
                                break;
                            }
                        }
                        if (blnAdd)
                        {
                            Ebook ebookImport = new Ebook();
                            ebookImport = dtoImport.Ebooks.ElementAt(i);
                            ebookImport.Path = Constants.StorageStructure.EbookFolder +
                                               Constants.CommonCharacters.SlashString + ebookImport.Title +
                                               ebookImport.Type;
                            ebookImport.BookmarkPath = Constants.StorageStructure.EbookFolder +
                                                       Constants.CommonCharacters.SlashString + ebookImport.Title +
                                                       Constants.XmlExtension;
                            DAO dao = new DAO(_dto);
                            dao.InsertEbook(ebookImport);
                            dicEbooks.Add(dtoImport.Ebooks.ElementAt(i).Id,
                                          _dto.Ebooks.ElementAt(_dto.Ebooks.Count - 1).Id);
                            Utilities.CopyFile(
                                strEbookImportPath + Constants.CommonCharacters.SlashString + ebookImport.Title +
                                ebookImport.Type,
                                Constants.StorageStructure.EbookFolder + Constants.CommonCharacters.SlashString +
                                ebookImport.Title + ebookImport.Type);
                            Utilities.CopyFile(
                                strEbookImportPath + Constants.CommonCharacters.SlashString + ebookImport.Title +
                                Constants.XmlExtension,
                                Constants.StorageStructure.EbookFolder + Constants.CommonCharacters.SlashString +
                                ebookImport.Title + Constants.XmlExtension);
                        }
                    }
                }

                _syncManager.SyncEbookGroup(_dto, dtoImportTemp1);
                _syncManager.SyncNote(_dto, dtoImportTemp2);
                _syncManager.SyncNoteDetail(_dto, dtoImportTemp3);
            }
            OpenEbookTab();
        }

        private void OpenFileHandler(object sender, RoutedEventArgs e)
        {
            OpenFileDialog myOpenFileDg = new OpenFileDialog();
            myOpenFileDg.Filter = Constants.FileFilter.PdfEpub;
            if (myOpenFileDg.ShowDialog() == true)
            {
                FileInfo myFile = new FileInfo(myOpenFileDg.FileName);
                string tabheader = Path.GetFileNameWithoutExtension(myFile.Name);
                // check if the tab already opened
                if (!CheckTabExist(tabheader))
                {
                    int count = _tabItems.Count;

                    // add new tabItem 
                    TabItem tab = new TabItem();
                    tab.Header = tabheader;
                    tab.Name = CreateNewTagName();
                    tab.HeaderTemplate = tabDynamic.FindResource(TabHeader) as DataTemplate;

                    // add controls to tab item
                    string fileName = Path.GetFileName(myFile.FullName);
                    ReaderGUI.ReaderGui reader = new ReaderGUI.ReaderGui(myFile.FullName, _dto);
                    _openingEbook.Add(tabheader,reader);
                    Grid readerTab = reader.GetReaderTab();
                    tab.Content = readerTab;
                    tab.Tag = reader;

                    // add tab into list tab items
                    _tabItems.Insert(count, tab);

                    // bind tab control
                    tabDynamic.Items.Add(tab);

                    // select newly added tab item
                    tabDynamic.SelectedItem = tab;
                }
            }
        }

        public void OpenNewEbook(string filePath, int pageNo)
        {
            FileInfo myFile = new FileInfo(filePath);
            string tabheader = Path.GetFileNameWithoutExtension(myFile.Name);
            // check if the tab already opened
            if (!CheckTabExist(tabheader))
            {
                int count = _tabItems.Count;

                // add new tabItem 
                TabItem tab = new TabItem();
                tab.Header = tabheader;
                tab.Name = CreateNewTagName();
                tab.HeaderTemplate = tabDynamic.FindResource(TabHeader) as DataTemplate;


                // add controls to tab item
                ReaderGui reader = new ReaderGui(myFile.FullName, _dto);
                _openingEbook.Add(tabheader, reader);
                Grid readerTab = reader.GetReaderTab();
                tab.Content = readerTab;
                tab.Tag = reader;

                // add tab into list tab items
                _tabItems.Insert(count, tab);

                // bind tab control
                tabDynamic.Items.Add(tab);

                // select newly added tab item
                tabDynamic.SelectedItem = tab;
                if (pageNo > 0)
                {
                    reader.txtPageNo.Text = pageNo.ToString();
                    ButtonAutomationPeer peer =
                        new ButtonAutomationPeer(reader.btGotoPage);
                    IInvokeProvider invokeProv =
                        peer.GetPattern(PatternInterface.Invoke)
                        as IInvokeProvider;
                    invokeProv.Invoke();
                }
            }
        }

        public void ReloadEbookTabLanguage(string oldTabHeader)
        {
            if (CheckTabExist(oldTabHeader))
            {
                int index = GetIndexOfSelectedItem(oldTabHeader);
                TabItem ebookTab = (TabItem) tabDynamic.Items[index];
                ebookTab.Header = ResourceReader.GetResourceContent(EbookTabName);
                _library.ReloadFormLanguage();
            }
        }

        //Add EBook
        private void OpenEBookTab(object sender, RoutedEventArgs e)
        {
            String tabheader = ResourceReader.GetResourceContent(EbookTabName);
            // check if the tab already opened
            if (!CheckTabExist(tabheader))
            {
                int count = _tabItems.Count;

                // add new tabItem 
                TabItem tab = new TabItem();
                tab.Header = tabheader;
                tab.Name = CreateNewTagName();
                tab.HeaderTemplate = tabDynamic.FindResource(TabHeader) as DataTemplate;


                // add controls to tab item
                _library = new LibraryGUI.LocalLibrary(_dto, this);
                Grid libraryTab = _library.GetLibraryTab();
                tab.Content = libraryTab;

                // add tab into list tab items
                _tabItems.Insert(count, tab);

                // bind tab control
                tabDynamic.Items.Add(tab);

                // select newly added tab item
                tabDynamic.SelectedItem = tab;
            }
            else
            {
                _library.RebindBookListData(_library.GetCheckedItem());
                _library.RebindRecentReadData();
                tabDynamic.SelectedIndex = GetIndexOfSelectedItem(tabheader);
            }
        }

        private void OpenEbookTab()
        {
            String tabheader = ResourceReader.GetResourceContent(EbookTabName);
            // check if the tab already opened
            if (!CheckTabExist(tabheader))
            {
                int count = _tabItems.Count;
                // add new tabItem 
                TabItem tab = new TabItem();
                tab.Header = ResourceReader.GetResourceContent(EbookTabName);
                tab.Name = CreateNewTagName();
                tab.HeaderTemplate = tabDynamic.FindResource(TabHeader) as DataTemplate;


                // add controls to tab item
                _library = new LibraryGUI.LocalLibrary(_dto, this);
                Grid libraryTab = _library.GetLibraryTab();
                tab.Content = libraryTab;

                // add tab into list tab items
                _tabItems.Insert(count, tab);

                // bind tab control
                tabDynamic.Items.Add(tab);

                // select newly added tab item
                tabDynamic.SelectedItem = tab;
            }
            else
            {
                _library.RebindBookListData(_library.GetCheckedItem());
                _library.RebindRecentReadData();
                tabDynamic.SelectedIndex = GetIndexOfSelectedItem(tabheader);
            }
        }

        public void ReloadNoteTabLanguage(string oldTabHeader)
        {
            if (CheckTabExist(oldTabHeader))
            {
                int index = GetIndexOfSelectedItem(oldTabHeader);
                TabItem noteTab = (TabItem) tabDynamic.Items[index];
                noteTab.Header = ResourceReader.GetResourceContent(NoteTabName);
                _noteManagement.ReloadFormLanguage();
            }
        }

        //Add Note
        private void OpenNoteTab(object sender, RoutedEventArgs e)
        {
            String tabheader = ResourceReader.GetResourceContent(NoteTabName);
            // check if the tab already opened
            if (!CheckTabExist(tabheader))
            {
                int count = _tabItems.Count;

                // add new tabItem 
                TabItem tab = new TabItem();
                tab.Header = tabheader;
                tab.Name = CreateNewTagName();
                tab.HeaderTemplate = tabDynamic.FindResource(TabHeader) as DataTemplate;


                // add controls to tab item
                _noteManagement = new DictionaryGUI.NoteManagement(_dto, this);
                Grid noteMangementTab = _noteManagement.GetNoteManagementTab();
                tab.Content = noteMangementTab;

                // add tab into list tab items
                _tabItems.Insert(count, tab);

                // bind tab control
                tabDynamic.Items.Add(tab);

                // select newly added tab item
                tabDynamic.SelectedItem = tab;
            }
            else
            {
                if (String.IsNullOrEmpty(_noteManagement.txtSearch.Text))
                {
                    _noteManagement.RebindNoteList(_dto.Note);
                }
                tabDynamic.SelectedIndex = GetIndexOfSelectedItem(tabheader);
            }
        }

        public void ReloadSettingTabLanguage(string oldTabHeader)
        {
            if (CheckTabExist(oldTabHeader))
            {
                int index = GetIndexOfSelectedItem(oldTabHeader);
                TabItem settingTab = (TabItem) tabDynamic.Items[index];
                settingTab.Header = ResourceReader.GetResourceContent(SettingName);
                _setting.ReloadFormLanguage();
            }
        }

        public void ReloadEbooksTabLanguage()
        {
            foreach (string tempHeader in _openingEbook.Keys)
            {
                if(CheckTabExist(tempHeader))
                {
                    _openingEbook[tempHeader].ReloadFormLanguage();
                }
            }
        }

        //Add Setting
        private void OpenSettingTab(object sender, RoutedEventArgs e)
        {
            String tabheader = ResourceReader.GetResourceContent(SettingName);
            // check if the tab already opened
            if (!CheckTabExist(tabheader))
            {
                int count = _tabItems.Count;

                // add new tabItem 
                TabItem tab = new TabItem();
                tab.Header = tabheader;
                tab.Name = CreateNewTagName();
                tab.HeaderTemplate = tabDynamic.FindResource(TabHeader) as DataTemplate;

                // add controls to tab item
                _setting = new SettingGUI.Setting(_dto, this);
                Grid gSettingTab = _setting.GetSettingTab();
                tab.Content = gSettingTab;

                // add tab into list tab items
                _tabItems.Insert(count, tab);

                // bind tab control
                tabDynamic.Items.Add(tab);

                // select newly added tab item
                tabDynamic.SelectedItem = tab;
            }
            else
            {
                tabDynamic.SelectedIndex = GetIndexOfSelectedItem(tabheader);
            }
        }

        private bool CheckTabExist(String tabHeader)
        {
            bool flag = false;
            for (int i = 0; i < _tabItems.Count; i++)
            {
                String tabItemCompared = _tabItems.ElementAt(i).Header.ToString();
                if (tabHeader.Equals(tabItemCompared))
                {
                    flag = true;
                }
            }
            return flag;
        }

        private int GetIndexOfSelectedItem(string tabHeader)
        {
            for (int i = 0; i < _tabItems.Count; i++)
            {
                string tabItemCompared = _tabItems.ElementAt(i).Header.ToString();
                if (tabItemCompared.Equals(tabHeader))
                {
                    return i;
                }
            }
            return -1;
        }

        private void BtnDeleteClick(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            if (button != null)
            {
                string tabName = button.CommandParameter.ToString();
                var item = tabDynamic.Items.Cast<TabItem>().Where(i => i.Name.Equals(tabName)).SingleOrDefault();

                var tab = item;

                if (tab != null)
                {
                    // get selected tab
                    TabItem selectedTab = tabDynamic.SelectedItem as TabItem;

                    // clear tab control binding
                    //tabDynamic.DataContext = null;
                    var getTabItemContent = (Window) tab.Tag;
                    if (getTabItemContent != null)
                    {
                        getTabItemContent.Close();
                    }
                    if(_openingEbook.ContainsKey(selectedTab.Header.ToString()))
                    {
                        _openingEbook.Remove(selectedTab.Header.ToString());
                    }
                    _tabItems.Remove(tab);

                    // bind tab control
                    tabDynamic.Items.Remove(tab);

                    // select previously selected tab. if that is removed then select first tab
                    if (selectedTab == null || selectedTab.Equals(tab))
                    {
                        if (_tabItems.Count != 0)
                        {
                            selectedTab = _tabItems[0];
                        }
                    }
                    tabDynamic.SelectedItem = selectedTab;
                    //}
                }
            }
        }

        private void WindowClosedHandler(object sender, EventArgs e)
        {
            System.Windows.Application.Current.Shutdown();
        }

        private void btExit_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Application.Current.Shutdown();
        }

        public void SetStatus(string content)
        {
            txtStatus.Content = content;
        }

        private void HandleChangeTabItem(object sender, SelectionChangedEventArgs e)
        {
            if (tabDynamic.SelectedItem != null)
            {
                string tabHeader = "";
                TabItem selectedItem = (TabItem) tabDynamic.SelectedItem;
                if (selectedItem != null)
                {
                    tabHeader = selectedItem.Header.ToString();
                }
                if (_currentTabHeader != tabHeader)
                {
                    if (ResourceReader.GetResourceContent(EbookTabName).Equals(tabHeader))
                    {
                        if (_library != null)
                        {
                            _library.RebindBookListData(_library.GetCheckedItem());
                            _library.RebindGroupData();
                            _library.RebindRecentReadData();
                        }
                    }
                    if (ResourceReader.GetResourceContent(NoteTabName).Equals(tabHeader))
                    {
                        if (_noteManagement != null)
                        {
                            if (String.IsNullOrEmpty(_noteManagement.txtSearch.Text))
                            {
                                _noteManagement.RebindNoteList(_dto.Note);
                            }
                        }
                    }
                    tabDynamic.SelectedIndex = GetIndexOfSelectedItem(tabHeader);
                    _currentTabHeader = tabHeader;
                }
            }
        }
    }
}